/**
 * Created by IntelliJ IDEA.
 * User: scotthatcher
 * Date: Mar 23, 2010
 * Time: 11:40:46 AM
 * To change this template use File | Settings | File Templates.
 */

import acm.graphics.GObject;
import acm.graphics.GOval;
import acm.graphics.GPoint;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;
import acm.util.RandomGenerator;


import java.awt.*;
import java.awt.event.MouseEvent;

public class Breakout2 extends GraphicsProgram {

    /** Width and height of application window in pixels */
    public static final int APPLICATION_WIDTH = 400;
    public static final int APPLICATION_HEIGHT = 600;

    /** Dimensions of game board (usually the same) */
    private static final int WIDTH = APPLICATION_WIDTH;
    private static final int HEIGHT = APPLICATION_HEIGHT;

    /** Dimensions of the paddle */
    private static final int PADDLE_WIDTH = 60;
    private static final int PADDLE_HEIGHT = 10;

    /** Offset of the paddle up from the bottom */
    private static final int PADDLE_Y_OFFSET = 30;

    /** Number of bricks per row */
    private static final int NBRICKS_PER_ROW = 10;

    /** Number of rows of bricks */
    private static final int NBRICK_ROWS = 10;

    /** Separation between bricks */
    private static final int BRICK_SEP = 4;

    /** Width of a brick */
    private static final int BRICK_WIDTH = (WIDTH -
            (NBRICKS_PER_ROW - 1) * BRICK_SEP) /
            NBRICKS_PER_ROW;

    /** Height of a brick */
    private static final int BRICK_HEIGHT = 8;

    /** Radius of the ball in pixels */
    private static final int BALL_RADIUS = 10;

    /** Offset of the top brick row from the top */
    private static final int BRICK_Y_OFFSET = 70;

    /** Number of turns */
    private static final int NTURNS = 3;

    /** Animation delay or pause time between ball moves */
    private static final int DELAY = 20;


    private void SetupPaddle(){
        Paddle = new GRect((APPLICATION_WIDTH - PADDLE_WIDTH)/2,
                APPLICATION_HEIGHT-PADDLE_Y_OFFSET, PADDLE_WIDTH,
                PADDLE_HEIGHT);
		Paddle.setFilled(true);
        add (Paddle);
    }
    private void StartBall(){
        SetupPaddle();
        CreateBall();
        while (ball.getY() < HEIGHT-BALL_RADIUS) {
                checkForCollision_X();
                checkForCollision_Y();
                getCollidingObject(ball.getX(),(ball.getY()));
                getCollidingObject((ball.getX()+(2*BALL_RADIUS)),(ball.getY()));
                getCollidingObject(ball.getX()+(2*BALL_RADIUS),(ball.getY()));
                getCollidingObject(ball.getX()+(2*BALL_RADIUS),(ball.getY())+(2*BALL_RADIUS));
                if (getElementAt(ball.getX(),(ball.getY()+BALL_RADIUS)) == Paddle){
                    vy = -vy;}
                moveBall();
                pause(DELAY);
                }
         remove (ball);
         remove (Paddle);
    }

    public void run() {
        /*GRect Background = new GRect(0,0,WIDTH,HEIGHT);
        Background.setFilled(true);
        Background.setColor(Color.lightGray);
        add (Background);  */
        SetupBricks();
        addMouseListeners();
        vx = rgen.nextDouble(1.0, 3.0);
            if (rgen.nextBoolean(0.5)) vx = -vx;
        vy = 3.0;
        for (int i = 0; i < 3; i++ ) {
            StartBall();

    }
              
        
    }

    public void SetupBricks(){
        int RowNumber = 0;
        for (int j = 0; j < NBRICK_ROWS; j++)  {
            for (int i = 0; i < NBRICKS_PER_ROW; i++)  {
                double XLocation = (i*BRICK_WIDTH)+(i*BRICK_SEP);
                double YLocation = BRICK_Y_OFFSET + (RowNumber*
                        BRICK_HEIGHT) + (RowNumber*BRICK_SEP);
                GRect Brick = new GRect(XLocation,YLocation,
                        BRICK_WIDTH,BRICK_HEIGHT);
                Brick.setFilled(true);
                if      (RowNumber<2)  Brick.setColor(Color.red);
                else if (RowNumber<4)  Brick.setColor(Color.orange);
                else if (RowNumber<6)  Brick.setColor(Color.yellow);
                else if (RowNumber<8)  Brick.setColor(Color.green);
                else                   Brick.setColor(Color.cyan);
                add (Brick);

            }
            RowNumber++;
    }
    }
    

    // Called on mouse press to record the coordinates of the click */
	public void mousePressed(MouseEvent e) {
		// GPoint has X and Y coordinate
		last = new GPoint(e.getPoint());
		gobj = getElementAt(last);
}



    // Called on mouse drag to reposition the object
    public void mouseDragged(MouseEvent e) {
    if (gobj != null && e.getX() <= APPLICATION_WIDTH && e.getX() > 0 && gobj == Paddle) {
        gobj.move(e.getX() - last.getX(),0);
        last = new GPoint(e.getPoint());
    }
    }
    private void CreateBall(){
        ball = new GOval((WIDTH-BALL_RADIUS)/2,HEIGHT/3 ,BALL_RADIUS,BALL_RADIUS);
        ball.setFilled(true);
        add (ball);
    }
   private void moveBall() {

		ball.move(vx,vy);
		}

	/** Determine if collision with floor, update velocities
	 * and location as appropriate. */
	private void checkForCollision_Y() {
		// determine if ball has dropped below the floor
		if (ball.getY() >= HEIGHT-BALL_RADIUS || ball.getY() <= 3 + BALL_RADIUS) {

	    // change ball's X velocity
	    vy = -vy;
        }
    }
    private void checkForCollision_X() {
        // determine if ball has dropped below the floor
        if (ball.getX() >= WIDTH - BALL_RADIUS || ball.getX() <= 3 +
                BALL_RADIUS) {

        ///change ball's Y velocity
        vx = -vx;

       }
       }
    public GObject getCollidingObject(double x, double y){
        GObject Collider = getElementAt(x,y);
        if (Collider == Paddle){
                vy = -vy;}
        else if (Collider == null){
            return (null);
        }
        else {
            remove (Collider);
            vy = -vy;
        }
        return(Collider);
    }



    private GObject gobj;	//The object being dragged
	private GPoint last;	//The last mouse position
	private RandomGenerator rgen = RandomGenerator.getInstance();
    private GOval ball;
    private GRect Paddle;
    private double vx;
    private double vy;


}